package collection;

import java.util.Iterator;

import exception.CollectionEmptyException;

public class OrdTree<E> extends ATree<OrdTreeNode<E>, E> {

	private OrdTreeNode<E> root = null;
	private int size = 0;
	
	public OrdTree() {}

	@Override
	public OrdTreeNode<E> createNode(E element) 
	{
		return new OrdTreeNode<E>(element);
	}

	@Override
	public boolean isInternal(OrdTreeNode<E> someNode) 
	{
		return getChildren(someNode).iterator().hasNext();
	}

	@Override
	public boolean isExternal(OrdTreeNode<E> someNode) 
	{
		return !isInternal(someNode);
	}

	@Override
	public OrdTreeNode<E> getParent(OrdTreeNode<E> someNode) 
	{
		return someNode.getParent();
	}
	
	public void setParent(OrdTreeNode<E> someNode, OrdTreeNode<E> parentNode)
	{
		someNode.setParent(parentNode);
	}

	@Override
	public Iterable<OrdTreeNode<E>> getChildren(final OrdTreeNode<E> someNode) 
	{
		return new Iterable<OrdTreeNode<E>>()
				{

					@Override
					public Iterator<OrdTreeNode<E>> iterator() 
					{
						return someNode.getChildren().elementsIterator();
					}
					
				};
	}
	
	public void addChild(OrdTreeNode<E> someNode, OrdTreeNode<E> childNode)
	{
		someNode.addChild(childNode);
		childNode.setParent(someNode);
		this.size += 1;
	}
	
	public void addChildElement(OrdTreeNode<E> someNode, E element)
	{
		addChild(someNode, createNode(element));
		this.size += 1;
	}

	@Override
	public int size() 
	{
		return this.size;
	}

	@Override
	public OrdTreeNode<E> getRoot() throws CollectionEmptyException 
	{
		if (isEmpty())
			throw new CollectionEmptyException("Ordered Tree");
		else
			return this.root;
	}

	@Override
	public OrdTreeNode<E> createRoot(E element) 
	{
		this.root = new OrdTreeNode<E>(element);
		this.size += 1;
		return root;
	}

	@Override
	public boolean isRoot(OrdTreeNode<E> someNode) 
	{
		return someNode == this.root;
	}

}
